package org.ala.tiktools.sharddb;

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;

import java.util.*;

/**
 * 统一前缀解析配置工具类
 *
 * @author ala
 * @date 2024-12-27 11:04
 */
public class ConfigPrefixParser {


    /**
     *  统一前缀
     */
    protected String prefix;
    /**
     *  统一前缀键值对集合
     */
    protected PropertyValues pvs;
    /**
     *  统一前缀键值对
     */
    protected Map<String, Map<String, Object>> map;

    public ConfigPrefixParser(Environment env, String pre) {
        this.prefix = pre;
        this.pvs = subProperties(env, pre);
        this.map = allKeys();
    }

    /**
     *  解析前缀下所有的key
     */
    public Map<String, Map<String, Object>> allKeys() {
        String prefix = String.format("%s.", this.prefix);
        Map<String, Map<String, Object>> map = new HashMap<>();
        for (PropertyValue pv : pvs) {
            String name = pv.getName();
            if (name.startsWith(prefix)) {
                String pname = name.split("\\.")[1];
                map.computeIfAbsent(pname, k -> new HashMap<>()).put(name, pv.getValue());
            }
        }
        Map<Integer, Long> m = new HashMap<>();
        m.merge(1, 1l, Long::sum);
        return map;
    }


    /**
     * 获取子参数集
     * @param env 环境上下文
     * @param pre 参数前缀
     * @return 子参数集
     */
    @SuppressWarnings("rawtypes")
    protected PropertyValues subProperties(Environment env, String pre) {
        MutablePropertyValues mpvs = new MutablePropertyValues();
        Collection<String> ns = new HashSet<>();
        for (PropertySource<?> propertySource : ((AbstractEnvironment) env).getPropertySources()) {
            if (propertySource instanceof EnumerablePropertySource) {
                String[] propertyNames = ((EnumerablePropertySource) propertySource).getPropertyNames();
                for (String name : propertyNames) {
                    if (name.startsWith(pre)) {
                        if (!ns.add(name)) continue;
                        mpvs.addPropertyValue(name, env.getProperty(name));
                    }
                }
            }
        }
        return mpvs;
    }
}
